//
// Created by DELL on 2021/9/6.
// 多线程
//

#include "iostream"
#include "pthread.h"
#include "cstdlib"
#include "unistd.h"

using namespace std;

#define NUM_THREADS 5

struct thread_data {
    int thread_id;
    char *mess;
};

// 线程执行函数
void *sayHello(void *threadId);

void *printHello(void *thread);

void *wait(void *t);

int main() {
    //===============创建线程=====================
/*    pthread_t tids[NUM_THREADS];
    int indexes[NUM_THREADS];
    int rec;
    for (int i = 0; i < NUM_THREADS; ++i) {
        cout << "create thread:" << i << endl;
        indexes[i] = i;
        //参数依次是：创建的线程id，线程参数，调用的函数，传入的函数参数
        rec = pthread_create(&tids[i], nullptr, sayHello, (void *) &(indexes[i]));
        // rec = pthread_create(tids+i, nullptr, sayHello, (void *)(indexes+i));
        if (rec != 0) {
            cout << "thread create fail:" << rec << endl;
            exit(-1);
        }
    }*/
    //===============创建线程=====================

    //===============向线程传递参数（结构体）=====================

/*    int rec;
    pthread_t tids[NUM_THREADS];
    struct thread_data td[NUM_THREADS];
    for (int i = 0; i < NUM_THREADS; ++i) {
        cout << "create thread, " << i << endl;
        td[i].thread_id = i;
        td[i].mess = (char *) "this is mess";
        rec = pthread_create(&tids[i], nullptr, printHello, (void *) &(td[i]));
        if (rec != 0) {
            cout << "Error:unable to create thread," << rec << endl;
            exit(-1);
        }
    }*/
    //===============向线程传递参数（结构体）=====================

    //===============连接和分离线程=====================

    int rec;
    pthread_t pths[NUM_THREADS];
    pthread_attr_t attr;
    void *status;

    // 初始化线程并设置为joinable
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    for (int i = 0; i < NUM_THREADS; ++i) {
        cout<< "main: creating thread, " << i << endl;

        rec = pthread_create(&pths[i], nullptr, wait, (void *)&i);

        if (rec != 0){
            cout<< "thread create fail." << rec << endl;
            exit(-1);
        }
    }

    pthread_attr_destroy(&attr);
    for (int i = 0; i < NUM_THREADS; ++i) {
        rec = pthread_join(pths[i], &status);

        if (rec != 0){
            cout << "fail to join, " << rec << endl;
            exit(-1);
        }

        cout << "completed thread id : " << i;
        cout << " exiting with status : " << status << endl;

    }
    //===============连接和分离线程=====================

    cout << "main exit..." << endl;

    pthread_exit(nullptr);

}

void *sayHello(void *threadId) {

    int th_id = *((int *) threadId);

    cout << "Hello, thread id = " << th_id << endl;

    pthread_exit(nullptr);
}

void *printHello(void *thread) {
    struct thread_data *my_data;

    my_data = (struct thread_data *) thread;

    cout << "thread id:" << my_data->thread_id;
    cout << " thread mess:" << my_data->mess << endl;

    pthread_exit(nullptr);

}

void *wait(void *t) {
    long tid = *((long*)t);

    sleep(1);

    cout << "Sleeping in thread " << endl;
    cout << "Thread with id : " << tid << "  ...exiting " << endl;

    pthread_exit(nullptr);
}